import calendar
import datetime


def get_last_friday(year, month):
  cal = calendar.Calendar(4)  # Make Friday the first day.
  week_list = cal.monthdayscalendar(year, month)
  fridays = [week[0] for week in week_list if week[0] != 0]
  return datetime.date(year, month, fridays[-1])


def get_expiry_from_code(code):
  assert len(code) == 3, 'Invalid code: %s' % code
  month_code = 'FGHJKMNQUVXZ'
  month = month_code.index(code[0]) + 1  # Will raise if not found.
  year = int('20' + code[1:])
  assert 2010 <= year <= 2030, 'Invalid year %s' % year
  return get_last_friday(year, month)

def get_base_and_quote(symbol):
  if symbol.endswith('USD'):
    idx = symbol.find('USD')
    base = symbol[:idx]
    quote = symbol[idx:]
    assert quote == 'USD', quote
  elif symbol.endswith('USDT'):
    idx = symbol.find('USDT')
    base = symbol[:idx]
    quote = symbol[idx:]
    assert quote == 'USDT', quote
  else:
    raise ValueError('Unable to get base and quote: %s' % symbol)
  return base, quote

def parse_native_symbol(native_symbol):
  try:
    expiry = get_expiry_from_code(native_symbol[-3:]).strftime('%Y%m%d')
    base, quote = get_base_and_quote(native_symbol[:-3])
  except:
    expiry = 'PERPETUAL'
    base, quote = get_base_and_quote(native_symbol)
  res = {'base': base, 'quote': quote, 'expiry': expiry}
  return res
